package com.github.baichuan.web.dto;

import com.github.baichuan.mapping.BeanMapper;
import lombok.Getter;
import lombok.Setter;
import org.springframework.data.domain.Page;

import java.util.List;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 分页查询结果
 */
@Getter
@Setter
public class Pagination<T> {
    /**
     * 总数据条数
     */
    private long total;
    /**
     * 每页条数
     */
    private int pageSize;
    /**
     * 总页数
     */
    private long totalPage;
    /**
     * 数据
     */
    private List<T> data;

    public Pagination(){}

    public Pagination(long total, int pageSize, List<T> data){
        if(pageSize < 1) {
            throw new IllegalArgumentException("pageSize must more than 0");
        }

        this.total = total;
        this.pageSize = pageSize;
        this.totalPage = Double.valueOf(Math.ceil((float)total / pageSize)).intValue();
        this.data = data;
    }

    public Pagination(long total, int pageSize, long totalPage, List<T> data) {
        this.total = total;
        this.pageSize = pageSize;
        this.totalPage = totalPage;
        this.data = data;
    }

    public <D> Pagination<D> map(Function<T, D> func){
        if(data == null) {
            throw new IllegalStateException("data不能为null");
        }

        List<D> list = data.stream().map(func).collect(Collectors.toList());
        return new Pagination<>(total, pageSize, totalPage, list);
    }

    public <D> Pagination<D> map(Class<D> clazz){
        Function<T, D> func = x -> BeanMapper.map(x, clazz);
        return map(func);
    }

    public <D> Pagination<D> map(Class<D> clazz, Set<String> properties){
        Function<T, D> func = x -> BeanMapper.map(x, clazz, properties);
        return map(func);
    }

    public static <T> Pagination<T> of(Page<T> page){
        return new Pagination<>(page.getTotalElements(), page.getSize(), page.getTotalPages(), page.getContent());
    }

}